package com.atdel.demo31;


import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;

/**
 * @BelongsProject: java_study
 * @BelongsPackage: com.atdel.demo31
 * @Author: Del
 * @CreateTime: 2025-03-30  16:54
 * @Description: TODO
 * @Version: 1.0
 */
public class Student {

    /**
     * 学生类，包含学生的姓名、性别和爱好等信息
     */
    private String name;

    /**
     * 性别字段，使用GenderValidation注解进行性别值的校验
     */
    @GenderValidation
    private String gender;

    /**
     * 爱好列表，使用HobbyDescription注解进行爱好描述和数量限制
     */
    @HobbyDescription(hobbies = {"篮球", "足球", "游泳", "阅读", "音乐"}, maxHobbies = 3)
    private List<String> hobbies;

    /**
     * 学生类的构造方法
     *
     * @param name 学生的姓名
     * @param gender 学生的性别，需符合GenderValidation注解定义的值
     * @param hobbies 学生的爱好列表，需符合HobbyDescription注解定义的爱好和数量限制
     */
    public Student(String name, String gender, List<String> hobbies) {
        this.name = name;
        setGender(gender);
        setHobbies(hobbies);
    }

    /**
     * 设置性别
     * 通过反射获取gender字段上的GenderValidation注解，根据注解的allowedValues进行性别值校验
     *
     * @param gender 性别值
     * @throws InvalidGenderException 如果性别值不在允许的范围内，则抛出无效性别异常
     */
    public void setGender(String gender) {
        try {
            Field genderField = this.getClass().getDeclaredField("gender");
            GenderValidation annotation = genderField.getAnnotation(GenderValidation.class);

            if (annotation != null) {
                String[] allowedValues = annotation.allowedValues();
                boolean isValid = false;

                for (String value : allowedValues) {
                    if (value.equalsIgnoreCase(gender)) {
                        isValid = true;
                        break;
                    }
                }

                if (!isValid) {
                    throw new InvalidGenderException("无效的性别值: " + gender +
                            "。允许的值: " + Arrays.toString(allowedValues));
                }
            }

            this.gender = gender;
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }

    /**
     * 设置爱好
     * 通过反射获取hobbies字段上的HobbyDescription注解，根据注解的hobbies和maxHobbies进行爱好校验和数量限制
     *
     * @param hobbies 爱好列表
     * @throws InvalidHobbyException 如果爱好数量超过限制或爱好不在允许的范围内，则抛出无效爱好异常
     */
    public void setHobbies(List<String> hobbies) {
        try {
            Field hobbiesField = this.getClass().getDeclaredField("hobbies");
            HobbyDescription annotation = hobbiesField.getAnnotation(HobbyDescription.class);

            if (annotation != null) {
                String[] allowedHobbies = annotation.hobbies();
                int maxHobbies = annotation.maxHobbies();

                if (hobbies.size() > maxHobbies) {
                    throw new InvalidHobbyException("爱好数量不能超过 " + maxHobbies);
                }

                for (String hobby : hobbies) {
                    boolean isValid = false;
                    for (String allowed : allowedHobbies) {
                        if (allowed.equalsIgnoreCase(hobby)) {
                            isValid = true;
                            break;
                        }
                    }
                    if (!isValid) {
                        throw new InvalidHobbyException("无效的爱好: " + hobby +
                                "。允许的爱好: " + Arrays.toString(allowedHobbies));
                    }
                }
            }

            this.hobbies = hobbies;
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }

    /**
     * 重写toString方法，返回学生的信息字符串
     *
     * @return 学生信息字符串，包括姓名、性别和爱好
     */
    @Override
    public String toString() {
        return "学生信息:\n" +
                "姓名: " + name + "\n" +
                "性别: " + gender + "\n" +
                "爱好: " + hobbies;
    }
}